/*
 * $Id: handler.cpp 417 2010-06-26 22:24:16Z cmtonkinson@gmail.com $
 *
 * This file is part of the Symphony project <http://code.google.com/p/symphonymud/>
 * Copyright 2005-2010 Chris Tonkinson <cmtonkinson@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <vector>
#include "avatar.h"
#include "color-string.h"
#include "commandTable.h"
#include "commandTable-default.h"
#include "display.h"
#include "handler.h"
#include "world.h"

/************************************** BASE CLASS HANDLE METHOD **************************************/
Handler::Handler( Creature* creature ) {
  this->creature( creature );
  this->avatar( (Avatar*)creature );
  this->commandTable( &(Commands::Instance()) );
  return;
}

bool Handler::handle( const std::string& text ) {
  Command* command = NULL;
  std::string input = text;
  std::vector<std::string> args;
  short max_num_args = 0;
  short negative_args = 0;
  bool status = false;
  unsigned long position = creature()->position().number();

  /* '!' is a shortcut for 'execute the previous command again.' */
  if ( input == "!" ) {
    input = lastInput();
  } else {
    lastInput( input );
  }

  /* Search the CommandTable for a match of the first token in `input`. */
  if ( ( command = commandTable()->find( input ) ) == NULL ) {
    creature()->send( "Huh?" );
    return false;
  }

  /* Make sure that the Creature is allowed to execute the
   * specified Command.  Assert:
   *   1) That the Creature has a high enough level
   *   2) That the Command is enabled
   *   3) Kirby Wuz Here
   *   4) That a "player only" command can't be executed by a Mob 
   */
  if ( creature()->level() < command->level() || !command->enabled() ) {
    creature()->send( "Huh?" );
    return false;
  }
  if ( command->playerOnly() ) {
    if ( creature()->isAvatar() ) {
      command->avatar( (Avatar*)creature() );
    } else {
      creature()->send( "Huh?" );
      return false;
    }
  }

  /* We need to make sure that the Creature is in one of the
   * allowed positions (sleeping, sitting, standing, etc) to
   * execute the Command.
   */
  if ( ( position & command->allowedPositions() ) != position ) {
    creature()->send( "You can't do that while %s.", creature()->position().string().c_str() );
    return false;
  }

  /* A Command has a std::set<short> called _arguments.  If this set contains positive
   * numbers (this is considered the general case) then we Regex::split() on the largest
   * of those numbers and then perform a check to ensure that the actual number of
   * arguments captured is valid.  There are two special cases:
   *
   * 1) When the first argument split() is empty, then no arguments were provided for the
   *    Command.  In this case, we assert that 0 is a valid number of arguments for the
   *    Command.  And example of this is the `look` Command:
   *        `look`         (zero arguments)
   *        `look chris`   (one argument)
   *    In the first case here, `look` is executed with no arguments, so we make a check
   *    that 0 is in Command::_arguments.
   *
   * 2) When we find a negative number (call it N) in _arguments, then the given Command
   *    expects a certain number of exact arguments followed by an arbitrary string.  In
   *    this case, the number of exact arguments is -(N+1) and the remaining text is
   *    part of the arbitraty string.  Examples are:
   *        `say hello there`                         (-1 arguments)
   *        `tell chris Hello there.`                 (-2 arguments)
   *        `restring sword shortname a neat sword`   (-3 arguments)
   *    So `say` expects only an arbitrary string.  `tell` expects one argument (the name
   *    of the target) and then an arbitrary string.  And so on.
   */

  // Get the largest number of accpted arguments and split()
  max_num_args = *command->arguments().rbegin();
  args = Regex::split( input, max_num_args );
  // This is special case #1 from above...
  if ( args[0].empty() ) {
    if ( command->arguments().find( 0 ) == command->arguments().end() ) {
      creature()->send( command->printSyntax() );
      return false;
    }
  // This is special case #2 from above...
  } else if ( ( negative_args = *command->arguments().begin() ) < 0 ) {
    args = Regex::split( input, -(negative_args+1) );
    if ( (signed)args.size() < (signed)-negative_args ) {
      creature()->send( command->printSyntax() );
      return false;
    }
  // This is the general case...
  } else {
    if ( command->arguments().find( args.size() ) == command->arguments().end() ) {
      creature()->send( command->printSyntax() );
      return false;
    }
  }

  // Reset the Avatar pointer after executing the command, just to be safe...
  status = command->execute( creature(), args );
  command->avatar( NULL );
  return status;
}

bool Handler::handle( void ) {
  return handle( avatar()->getInput() );
}

/************************************** LOGIN (BANNER) HANDLER **************************************/
void LoginBannerHandler::activate( void ) {
  avatar()->send( prompt() );
  avatar()->replaceHandler( new LoginNameHandler( avatar() ) );
  return;
}

void LoginBannerHandler::deactivate( void ) {
  return;
}

bool LoginBannerHandler::handle( void ) {
  return true;
}

std::string LoginBannerHandler::prompt( void ) {
  return "\n\n\n\n\n{RS{Gy{Ym{Bp{Mh{Co{Rn{Gy{W!!{x\n\n\n\n\n";
}

/************************************** LOGIN (NAME) HANDLER **************************************/
void LoginNameHandler::activate( void ) {
  return;
}

void LoginNameHandler::deactivate( void ) {
  return;
}

bool LoginNameHandler::handle( void ) {
  std::string input = ColorString(avatar()->getInput()).stripColor();
  input = Regex::trim( input.substr( 0, input.find_first_of(' ') ) );
  input[0] = toupper(input[0]); // Capitalize the first letter automatically.

  // Check to make sure that name isn't already signed in...
  if ( World::Instance().findAvatar( input ) ) {
    avatar()->send( "Sorry - they're already signed in.\n" );
    avatar()->disconnected( true );
    return false;
  }

  // Figure out whether or not the given name already exists...
  avatar()->identifiers().shortname( input );
  if ( avatar()->load() ) {
    avatar()->replaceHandler( new LoginPasswordHandler( avatar() ) );
    return true;
  } else {
    avatar()->send( "A newcomer, eh?\n" );
    avatar()->status().set( CREATING );
    avatar()->replaceHandler( new CreationNameHandler( avatar() ) );
    return true;
  }
}

std::string LoginNameHandler::prompt( void ) {
  return "Name: ";
}

/************************************** LOGIN (PASSWORD) HANDLER **************************************/
void LoginPasswordHandler::activate( void ) {
  avatar()->send( "\n" );
  return;
}

void LoginPasswordHandler::deactivate( void ) {
  return;
}

bool LoginPasswordHandler::handle( void ) {
  std::string input = avatar()->getInput();
  estring fd = avatar()->socket()->getFd();
  input = Regex::trim( input.substr( 0, input.find_first_of(' ') ) );

  if ( avatar()->checkPassword( input ) ) {
    if ( avatar()->deleteMe() ) {
      avatar()->replaceHandler( new LoginDeleteHandler( avatar() ) );
      return true;
    }
    World::Instance().bigBrother( avatar(), ADMIN_BIGBRO_LOGINS, "%s has logged in from %s.", avatar()->identifiers().shortname().c_str(), avatar()->socket()->getIP().c_str() );
    World::Instance().playerLog( NOTICE, LOG_PLAYER, "%s (%lu) logged in from %s", avatar()->identifiers().shortname().c_str(), avatar()->ID(), avatar()->socket()->getIP().c_str() );
    World::Instance().removeAvatar( fd );
    World::Instance().insert( avatar() );
    avatar()->status().set( CONNECTED );
    avatar()->replaceHandler( new InputHandler( avatar() ) );
    avatar()->send( "\nWecome back!\n" );
    avatar()->restoreRoom();
    return true;
  } else {
    avatar()->send( "That password is invalid.\n" );
    avatar()->deleteMe( false );
    avatar()->markForDeletion( 0 );
    avatar()->disconnected( true );
    return false;
  }
}

std::string LoginPasswordHandler::prompt( void ) {
  return "Password: ";
}

/************************************** LOGIN (DELETE) HANDLER **************************************/
void LoginDeleteHandler::activate( void ) {
  avatar()->deleteMe( false );
  avatar()->send( "\n" );
  return;
}

void LoginDeleteHandler::deactivate( void ) {
  return;
}

bool LoginDeleteHandler::handle( void ) {
  if ( avatar()->getInput() == "delete" ) {
    avatar()->send( "\n{RCharacter deleted.{x\n\nFarewell, traveler. May you find happiness in another realm.\n" );
    avatar()->deleteMe( true );
    avatar()->disconnected( true );
  } else {
    avatar()->markForDeletion( 0 );
    avatar()->send( "\nCharacter deletion {YCANCELLED{x!!  Whew - that was a close one." );
  }
  avatar()->replaceHandler( new InputHandler( avatar() ) );
  return true;
}

std::string LoginDeleteHandler::prompt( void ) {
  return "{RThis character has been marked for deletion!{x\n\
To delete this character, enter \"delete\" - any other input will cancel\n\
the process and log you into the game.\n\
Note: Character deletion IS permanent. All data will be instantly lost.";
}

/************************************** CREATION (NAME) HANDLER **************************************/
void CreationNameHandler::activate( void ) {
  avatar()->send( "\n" );
  return;
}

void CreationNameHandler::deactivate( void ) {
  return;
}

bool CreationNameHandler::handle( void ) {
  std::string input = ColorString(avatar()->getInput()).stripColor();
  input = Regex::trim( input.substr( 0, input.find_first_of(' ') ) );
  if ( input == "yes" ) {
    avatar()->send( "Sure it is!\n" );
    avatar()->replaceHandler( new CreationPasswordHandler(avatar() ) );
    return false;
  } else {
    avatar()->send( "My mistake!\n" );
    avatar()->identifiers().shortname( estring(avatar()->socket()->getFd()) );
    avatar()->replaceHandler( new LoginBannerHandler( avatar() ) );
    return false;
  }
}

std::string CreationNameHandler::prompt( void ) {
  std::string output;
  output.append( "Your name is " ).append( avatar()->identifiers().shortname() ).append( ", then? [yes/no] " );
  return output;
}

/************************************** CREATION (PASSWORD) HANDLER **************************************/
void CreationPasswordHandler::activate( void ) {
  avatar()->send( "\n" );
  return;
}

void CreationPasswordHandler::deactivate( void ) {
  return;
}

bool CreationPasswordHandler::handle( void ) {
  std::string input = ColorString(avatar()->getInput()).stripColor();
  input = Regex::trim( input.substr( 0, input.find_first_of(' ') ) );
  if ( input.size() < 6 ) {
    avatar()->send( "Sorry - it needs to be at least 6 characters long. " );
    return false;
  } else {
    avatar()->password( input );
    avatar()->replaceHandler( new CreationPasswordConfirmHandler( avatar() ) );
    return true;
  }
}

std::string CreationPasswordHandler::prompt( void ) {
  return "You'll need a password (no spaces): ";
}

/************************************** CREATION (PASSWORD CONFIRM) HANDLER **************************************/
void CreationPasswordConfirmHandler::activate( void ) {
  avatar()->send( "\n" );
  return;
}

void CreationPasswordConfirmHandler::deactivate( void ) {
  return;
}

bool CreationPasswordConfirmHandler::handle( void ) {
  std::string input = ColorString(avatar()->getInput()).stripColor();
  input = Regex::trim( input.substr( 0, input.find_first_of(' ') ) );
  if ( input == avatar()->password() ) {
    avatar()->send( "Great - now on to more interesting matters.\n" );
    avatar()->replaceHandler( new CreationGenderHandler( avatar() ) );
    return true;
  } else {
    avatar()->send( "That doesn't match the other password. " );
    avatar()->replaceHandler( new CreationPasswordHandler( avatar() ) );
    return false;
  }
}

std::string CreationPasswordConfirmHandler::prompt( void ) {
  return "One more time to confirm the password: ";
}

/************************************** CREATION (GENDER) HANDLER **************************************/
void CreationGenderHandler::activate( void ) {
  avatar()->send( "\n" );
  return;
}

void CreationGenderHandler::deactivate( void ) {
  return;
}

bool CreationGenderHandler::handle( void ) {
  std::string input = ColorString(avatar()->getInput()).stripColor();
  input = Regex::trim( input.substr( 0, input.find_first_of(' ') ) );
  if ( input == "male" || input == "female" ) {
    avatar()->gender().set( input == "male" ? MALE : FEMALE );
    avatar()->send( "A %s indeed.\n", avatar()->gender().string().c_str() );
    avatar()->replaceHandler( new CreationRaceHandler( avatar() ) );
    return true;
  } else {
    avatar()->send( "Sorry, I didn't understand that... " );
    return false;
  }
}

std::string CreationGenderHandler::prompt( void ) {
  return "Are you male, or female? ";
}

/************************************** CREATION (RACE) HANDLER **************************************/
void CreationRaceHandler::activate( void ) {
  avatar()->send( "\n" );
  return;
}

void CreationRaceHandler::deactivate( void ) {
  return;
}

bool CreationRaceHandler::handle( void ) {
  std::string input = ColorString(avatar()->getInput()).stripColor();
  input = Regex::trim( input.substr( 0, input.find_first_of(' ') ) );
  if ( input == "human" ) {
    avatar()->race().set( HUMAN );
    avatar()->send( "A human it is!\n" );
  } else if ( input == "elf" ) {
    avatar()->race().set( ELF );
    avatar()->send( "An child of the forest you shall be!\n" );
  } else if ( input == "dwarf" ) {
    avatar()->race().set( DWARF );
    avatar()->send( "And a fine dwarf you'll make!\n" );
  } else if ( input == "goblin" ) {
    avatar()->race().set( GOBLIN );
    avatar()->send( "You're just the type for a goblin!\n" );
  } else {
    avatar()->send( "Sorry... I don't understand... " );
    return false;
  }
  avatar()->replaceHandler( new CreationClassHandler( avatar() ) );
  return true;
}

std::string CreationRaceHandler::prompt( void ) {
  std::string output( "The races of the land are:\n" );
  output.append( "\n  Human     The dominant race. Can be: mage, cleric, warrior, rogue" );
  output.append( "\n  Elf       Forest-dwelling humanoids. Can be: mage, cleric, warrior, rogue" );
  output.append( "\n  Dwarf     Mountain-dwelling humanoids. Can be: cleric, warrior" );
  output.append( "\n  Goblin    Mischevious and unkempt creatures. Can be: mage, warrior, rogue" );
  output.append( "\n\nWhich do you choose? " );
  return output;
}

/************************************** CREATION (CLASS) HANDLER **************************************/
void CreationClassHandler::activate( void ) {
  avatar()->send( "\n" );
  return;
}

void CreationClassHandler::deactivate( void ) {
  return;
}

bool CreationClassHandler::handle( void ) {
  std::string input = ColorString(avatar()->getInput()).stripColor();
  input = Regex::trim( input.substr( 0, input.find_first_of(' ') ) );
  if ( input == "mage" ) {
    avatar()->pClass().set( MAGE );
    avatar()->send( "You shall study the ways of arcane magic.\n" );
  } else if ( input == "cleric" ) {
    avatar()->pClass().set( CLERIC );
    avatar()->send( "You've chosen to follow the holy path.\n" );
  } else if ( input == "warrior" ) {
    avatar()->pClass().set( WARRIOR );
    avatar()->send( "Your physical prowess will be unmatched in combat.\n" );
  } else if ( input == "rogue" ) {
    avatar()->pClass().set( ROGUE );
    avatar()->send( "In stealth you will excel.\n" );
  } else {
    avatar()->send( "Sorry... I don't understand... " );
    return false;
  }
  avatar()->replaceHandler( new CreationSummaryHandler( avatar() ) );
  return true;
}

std::string CreationClassHandler::prompt( void ) {
  std::string output( "As a " );
  output.append( avatar()->race().string() ).append( " you may choose to be a:" );
  if ( avatar()->race().number() != DWARF ) {
    output.append( "\n  Mage     Mages are arcane casters, champions of illusion and enchantment" );
  }
  if ( avatar()->race().number() != GOBLIN ) {
    output.append( "\n  Cleric   Clerics are divine casters able to channel holy energy" );
  }
  output.append( "\n  Warrior  Warriors are armsmen, great at dealing (and taking) massive damage" );
  if ( avatar()->race().number() != DWARF ) {
    output.append( "\n  Rogue    Rogues are the perfect assassins - stealth is their trademark" );
  }
  output.append( "\n\nWhich class suits you? " );
  return output;
}

/************************************** CREATION (SUMMARY) HANDLER **************************************/
void CreationSummaryHandler::activate( void ) {
  avatar()->send( "\n" );
  return;
}

void CreationSummaryHandler::deactivate( void ) {
  return;
}

bool CreationSummaryHandler::handle( void ) {
  std::string input = ColorString(avatar()->getInput()).stripColor();
  input = Regex::trim( input.substr( 0, input.find_first_of(' ') ) );
  bool success = false;
  if ( input == "accept" ) {
    avatar()->adjustStartingStats();
    avatar()->status().set( CONNECTED );
    avatar()->room( World::Instance().findRoom( 0 ) );
    if ( avatar()->create() && avatar()->save() && avatar()->load() ) {
      avatar()->send( "Welcome to the realm, young %s!", avatar()->identifiers().shortname().c_str() );
      avatar()->restoreRoom();
      success = true;
    } else {
      avatar()->send( "Terribly sorry - there was a problem finalizing your account." );
      success = false;
    }
  } else {
    avatar()->send( "May you find happiness in your travels.\n" );
    success = false;
  }
  avatar()->replaceHandler( new InputHandler( avatar() ) );
  avatar()->disconnected( !success );
  return success;
}

std::string CreationSummaryHandler::prompt( void ) {
  std::string output( "A summary of your choices:" );
  output.append( "\n  Name:   {g" ).append( avatar()->identifiers().shortname() ).append( "{x" );
  output.append( "\n  Gender: {g" ).append( avatar()->gender().string() ).append( "{x" );
  output.append( "\n  Race:   {g" ).append( avatar()->race().string() ).append( "{x" );
  output.append( "\n  Class:  {g" ).append( avatar()->pClass().string() ).append( "{x" );
  output.append( "\n\nTo accept this configuration, type 'accept'." );
  output.append( "\nAny other input will cancel the process." );
  return output;
}

/************************************** NOTE (SUBJECT) HANDLER **************************************/
void NoteGetSubjectHandler::activate( void ) {
  avatar()->send( "\n" );
  return;
}

void NoteGetSubjectHandler::deactivate( void ) {
  return;
}

bool NoteGetSubjectHandler::handle( void ) {
  std::string input = ColorString(avatar()->getInput()).stripColor();
  avatar()->note()->subject( input );
  avatar()->composing().set( COMP_NOTE );
  Handler* h = new TeditHandler( avatar() );
  h->getState()["vector"] = (void*)(new std::vector<std::string>());
  h->getState()["name"] = (void*)(new std::string("Note Editor"));
  h->getState()["pointer"] = (void*)avatar()->note()->bodyp();
  avatar()->replaceHandler( h );
  avatar()->send( "Type `cancel` to abandon your note or `send` to finish it." );
  return true;
}

std::string NoteGetSubjectHandler::prompt( void ) {
  return "Subject: ";
}

/************************************** NOTE (SEND) HANDLER **************************************/
void NoteSendHandler::activate( void ) {
  avatar()->popHandler();
  return;
}

void NoteSendHandler::deactivate( void ) {
  avatar()->composing().set( 0 );
  avatar()->note()->save();
  World::Instance().boards()[avatar()->board()]->notes().insert( std::make_pair( avatar()->note()->ID(), avatar()->note() ) );
  avatar()->note( NULL );
  avatar()->send( "Your note has been sent." );
  return;
}

bool NoteSendHandler::handle( void ) {
  return true;
}

std::string NoteSendHandler::prompt( void ) {
  return "";
}

/************************************** NOTE (CANCEL) HANDLER **************************************/
void NoteCancelHandler::activate( void ) {
  avatar()->popHandler();
  return;
}

void NoteCancelHandler::deactivate( void ) {
  avatar()->composing().set( 0 );
  avatar()->note()->destroy();
  avatar()->note( NULL );
  avatar()->send( "Your note has been trashed." );
  return;
}

bool NoteCancelHandler::handle( void ) {
  return true;
}

std::string NoteCancelHandler::prompt( void ) {
  return "";
}

/************************************** MAIN HANDLER **************************************/
void InputHandler::activate( void ) {
  commandTable( &(Commands::Instance()) );
  return;
}

void InputHandler::deactivate( void ) {
  return;
}

std::string InputHandler::prompt( void ) {
  if ( avatar()->whoFlags().test( WHO_AFK ) ) {
    return "\n\n{x[{YAFK{x] ";
  } else {
    return "\n\n{x[{CSymphony{x] ";
  }
}

/************************************** AEDIT HANDLER **************************************/
void AeditHandler::activate( void ) {
  commandTable( &(AeditCommands::Instance()) );
  avatar()->whoFlags().set( WHO_BUSY );
  avatar()->mode().set( MODE_AEDIT );
  World::Instance().bigBrother( avatar(), ADMIN_BIGBRO_MODES, "%s has entered area editing mode.", avatar()->identifiers().shortname().c_str() );
  return;
}

void AeditHandler::deactivate( void ) {
  avatar()->send( "Goodbye!\n" );
  avatar()->whoFlags().clear( WHO_BUSY );
  avatar()->mode().set( MODE_NONE );
  World::Instance().bigBrother( avatar(), ADMIN_BIGBRO_MODES, "%s has left area editing mode.", avatar()->identifiers().shortname().c_str() );
  return;
}

std::string AeditHandler::prompt( void ) {
  char buffer[MAX_BUFFER];
  sprintf( buffer, "\n\n{W[{cAedit {x- {G%s{W] ", avatar()->aedit()->name().c_str() );
  return buffer;
}

/************************************** MEDIT HANDLER **************************************/
void MeditHandler::activate( void ) {
  commandTable( &(MeditCommands::Instance()) );
  avatar()->whoFlags().set( WHO_BUSY );
  avatar()->mode().set( MODE_MEDIT );
  World::Instance().bigBrother( avatar(), ADMIN_BIGBRO_MODES, "%s has entered mob editing mode.", avatar()->identifiers().shortname().c_str() );
  return;
}

void MeditHandler::deactivate( void ) {
  avatar()->send( "Goodbye!\n" );
  avatar()->whoFlags().clear( WHO_BUSY );
  avatar()->mode().set( MODE_NONE );
  World::Instance().bigBrother( avatar(), ADMIN_BIGBRO_MODES, "%s has left mob editing mode.", avatar()->identifiers().shortname().c_str() );
  return;
}

std::string MeditHandler::prompt( void ) {
  char buffer[MAX_BUFFER];
  sprintf( buffer, "\n\n{W[{cMedit {x- {G%lu{W] ", avatar()->medit()->vnum() );
  return buffer;
}

/************************************** OEDIT HANDLER **************************************/
void OeditHandler::activate( void ) {
  commandTable( &(OeditCommands::Instance()) );
  avatar()->whoFlags().set( WHO_BUSY );
  avatar()->mode().set( MODE_OEDIT );
  World::Instance().bigBrother( avatar(), ADMIN_BIGBRO_MODES, "%s has entered object editing mode.", avatar()->identifiers().shortname().c_str() );
  return;
}

void OeditHandler::deactivate( void ) {
  avatar()->send( "Goodbye!\n" );
  avatar()->whoFlags().clear( WHO_BUSY );
  avatar()->mode().set( MODE_NONE );
  World::Instance().bigBrother( avatar(), ADMIN_BIGBRO_MODES, "%s has left object editing mode.", avatar()->identifiers().shortname().c_str() );
  return;
}

std::string OeditHandler::prompt( void ) {
  char buffer[MAX_BUFFER];
  sprintf( buffer, "\n\n{W[{cOedit {x- {G%lu{W] ", avatar()->oedit()->vnum() );
  return buffer;
}

/************************************** PEDIT HANDLER **************************************/
void PeditHandler::activate( void ) {
  commandTable( &(PeditCommands::Instance()) );
  avatar()->whoFlags().set( WHO_BUSY );
  avatar()->mode().set( MODE_PEDIT );
  World::Instance().bigBrother( avatar(), ADMIN_BIGBRO_MODES, "%s has entered player editing mode.", avatar()->identifiers().shortname().c_str() );
  return;
}

void PeditHandler::deactivate( void ) {
  avatar()->send( "Goodbye!\n" );
  avatar()->whoFlags().clear( WHO_BUSY );
  avatar()->mode().set( MODE_NONE );
  World::Instance().bigBrother( avatar(), ADMIN_BIGBRO_MODES, "%s has left player editing mode.", avatar()->identifiers().shortname().c_str() );
  return;
}

std::string PeditHandler::prompt( void ) {
  char buffer[MAX_BUFFER];
  sprintf( buffer, "\n\n{W[{cPedit {x- {G%s{W] ", avatar()->pedit()->identifiers().shortname().c_str() );
  return buffer;
}

/************************************** REDIT HANDLER **************************************/
void ReditHandler::activate( void ) {
  commandTable( &(ReditCommands::Instance()) );
  avatar()->whoFlags().set( WHO_BUSY );
  avatar()->mode().set( MODE_REDIT );
  World::Instance().bigBrother( avatar(), ADMIN_BIGBRO_MODES, "%s has entered room editing mode.", avatar()->identifiers().shortname().c_str() );
  return;
}

void ReditHandler::deactivate( void ) {
  avatar()->send( "Goodbye!\n" );
  avatar()->whoFlags().clear( WHO_BUSY );
  avatar()->mode().set( MODE_NONE );
  World::Instance().bigBrother( avatar(), ADMIN_BIGBRO_MODES, "%s has left room editing mode.", avatar()->identifiers().shortname().c_str() );
  return;
}

std::string ReditHandler::prompt( void ) {
  char buffer[MAX_BUFFER];
  sprintf( buffer, "\n\n{W[{cRedit {x- {G%lu{W] ", avatar()->room()->vnum() );
  return buffer;
}

/************************************** SEDIT HANDLER **************************************/
void SeditHandler::activate( void ) {
  commandTable( &(SeditCommands::Instance()) );
  avatar()->whoFlags().set( WHO_BUSY );
  avatar()->mode().set( MODE_SEDIT );
  World::Instance().bigBrother( avatar(), ADMIN_BIGBRO_MODES, "%s has entered social editing mode.", avatar()->identifiers().shortname().c_str() );
  return;
}

void SeditHandler::deactivate( void ) {
  avatar()->send( "Goodbye!\n" );
  avatar()->whoFlags().clear( WHO_BUSY );
  avatar()->mode().set( MODE_NONE );
  World::Instance().bigBrother( avatar(), ADMIN_BIGBRO_MODES, "%s has left social editing mode.", avatar()->identifiers().shortname().c_str() );
  return;
}

std::string SeditHandler::prompt( void ) {
  char buffer[MAX_BUFFER];
  sprintf( buffer, "\n\n{W[{cSedit {x- {G%s{W] ", avatar()->sedit()->name().c_str() );
  return buffer;
}

/************************************** TEDIT HANDLER **************************************/
void TeditHandler::activate( void ) {
  commandTable( &(TeditCommands::Instance()) );
  avatar()->send( "Welcome to the Symphony Text Editor.\n" );
  return;
}

void TeditHandler::deactivate( void ) {
  std::vector<std::string>* v = (std::vector<std::string>*)getState()["vector"];
  std::string* s = (std::string*)getState()["name"];
  ((std::string*)getState()["pointer"])->assign( Regex::implode( "\n", *v ) );
  delete v;
  delete s;
  getState().clear();
  avatar()->send( "You've left the Symphony Text Editor.\n" );
  return;
}

std::string TeditHandler::prompt( void ) {
  char buffer[MAX_BUFFER];
  sprintf( buffer, "\n\n{W[{cCurrently Editing: {C%s{W] ", ((std::string*)getState()["name"])->c_str() );
  return buffer;
}
